package com.fs.jzzn.controller;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import lombok.extern.log4j.Log4j;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fs.base.pojo.Attachment;
import com.fs.base.pojo.PkEntity;
import com.fs.base.repository.AttachmentRepository;
import com.fs.base.utils.ApplicationUtils;
import com.fs.base.utils.DateUtils;
import com.fs.base.utils.ExcelUtils;
import com.fs.base.vo.DataGrid;
import com.fs.base.vo.JsonResponse;
import com.fs.base.vo.SysPath;
import com.fs.jzzn.pojo.AssistUnit;
import com.fs.jzzn.pojo.Contract;
import com.fs.jzzn.pojo.Expense;
import com.fs.jzzn.pojo.FixedAssets;
import com.fs.jzzn.pojo.Flow;
import com.fs.jzzn.pojo.Income;
import com.fs.jzzn.pojo.Information;
import com.fs.jzzn.pojo.Invoice;
import com.fs.jzzn.pojo.Materiel;
import com.fs.jzzn.pojo.Project;
import com.fs.jzzn.pojo.Task;
import com.fs.jzzn.repository.AssistUnitRepository;
import com.fs.jzzn.repository.ContractRepository;
import com.fs.jzzn.repository.ExpenseRepository;
import com.fs.jzzn.repository.FixedAssetsRepository;
import com.fs.jzzn.repository.IncomeRepository;
import com.fs.jzzn.repository.InformationRepository;
import com.fs.jzzn.repository.InvoiceRepository;
import com.fs.jzzn.repository.MaterielRepository;
import com.fs.jzzn.repository.ProjectRepository;
import com.fs.jzzn.service.FlowService;
import com.fs.jzzn.service.ProjectService;

/**
 * @author TiddlerCJ
 *
 */

@Controller
@Log4j
@RequestMapping("/console/project/rewrite")
public class ProjectController {
	@Autowired private ProjectRepository projectRepository;
	@Autowired private ContractRepository contractRepository;
	@Autowired private AssistUnitRepository assistUnitRepository;
	@Autowired private IncomeRepository incomeRepository;
	@Autowired private ExpenseRepository expenseRepository;
	@Autowired private InvoiceRepository invoiceRepository;
	@Autowired private ProjectService projectService;
	@Autowired private FlowService flowService;	
	@Autowired private AttachmentRepository attachmentRepository;
	@Autowired private InformationRepository informationRepository;
	@Autowired private MaterielRepository materielRepository;
	/**
	 * 项目信息模块页面跳转
	 * @param pageName
	 * @param req
	 * @return
	 */
	@RequestMapping("/{pageName}")
	public String pageName(@PathVariable String pageName, HttpServletRequest req){
		return SysPath.BACK_PATH.concat("/project/").concat(pageName);
	}
	
	/**
	 * 查看流程执行状态
	 * @param req
	 * @param id
	 * @return
	 */
	@RequestMapping("flow")
	public String flow(HttpServletRequest req,String id){
		Project project = projectRepository.findOne(id);
		if(project==null){
			req.setAttribute("message", "当前项目记录已经删除！");
		}else{
			/*String flowId = project.getFlowId();
			if(StringUtils.isNotBlank(flowId)){
				List<Flow> nodes = flowService.getFlowRepository().findByParentIdOrderByFlowOrderAsc(flowId);
				Flow currentNode = flowService.getCurrentNode(flowId, id);
				if(currentNode==null){
					currentNode = flowService.getFirstNode(flowId);
				}
				req.setAttribute("nodes", nodes);
				req.setAttribute("currentNodeId", currentNode==null? "": currentNode.getId());
			}*/
		}
		return SysPath.BACK_PATH.concat("/project/flow");
	}
	
	
	/**
	 * 审计页面
	 * @param modleName
	 * @param req
	 * @return
	 */
	@GetMapping("check")
	public String configGet(HttpServletRequest req) {
		return SysPath.BACK_PATH.concat("/project/check");
	}
	
	@GetMapping("print/{contractId}")
	public String print(@PathVariable String contractId,HttpServletRequest req) {
		String pId = req.getParameter("pId");
		
		Contract contract = contractRepository.getOne(contractId);
		req.setAttribute("contract", contract);
		
		if(contract!=null){
			AssistUnit unit = assistUnitRepository.findByName(contract.getAssistUnit());
			req.setAttribute("unit", unit);
		}
		
		req.setAttribute("tableTime", DateUtils.formatDate(new Date(), "yyyy年MM月dd日"));
		List<Project> projectList = null;
		if(StringUtils.isNotBlank(pId)){
			String [] idArrays = pId.split(",");
			List<String> ids = Arrays.asList(idArrays);
			projectList = projectRepository.findByIdIn(ids);
		}
		req.setAttribute("projectJson", JSON.toJSONString(projectList));
		return SysPath.BACK_PATH.concat("/project/print");
	}
	
	@GetMapping("autoCode")
	public String autoCode(HttpServletRequest req) {
		//req.setAttribute("projectJson", JSON.toJSONString(projectList));
		return SysPath.BACK_PATH.concat("/project/autoCode");
	}
	
	 
	 
	@GetMapping("unship")
	@ResponseBody
	public JsonResponse unship(HttpServletRequest request) {
		try {
			String id = request.getParameter(PkEntity.PRIMARY_KEY_NAME);
			if (StringUtils.isNotBlank(id)) {
				projectRepository.unship(id);
				return JsonResponse.success();
			}else{
				return JsonResponse.error("未指定记录id");
			}
		} catch (Exception e) {
			e.printStackTrace();
			log.error(e.getMessage());
			return JsonResponse.error(e.getMessage());
		}
	}
	@GetMapping("ship")
	@ResponseBody
	public JsonResponse ship(HttpServletRequest request) {
		try {
			String contractNo = request.getParameter("contractNo");
			if (StringUtils.isNotBlank(contractNo)) {
				String json = request.getParameter("json");
				if(StringUtils.isNotBlank(json)){
					JSONArray ids = (JSONArray) JSONArray.parse(json);
					for(int i=0,len=ids.size();i<len;i++){
						JSONObject item = ids.getJSONObject(i);
						projectRepository.ship(contractNo, item.getString("id"));
					}
				}
				return JsonResponse.success();
			}else{
				return JsonResponse.error("未指定记录id");
			}
		} catch (Exception e) {
			e.printStackTrace();
			log.error(e.getMessage());
			return JsonResponse.error(e.getMessage());
		}
	}
	
	
	@GetMapping("count")
	@ResponseBody
	public JsonResponse count(HttpServletRequest request) {
		try {
			JSONObject count = new JSONObject();
			count.put("contractCount", contractRepository.count());
			count.put("projectCount", projectRepository.count());
			count.put("incomeCount", incomeRepository.count());
			count.put("invoiceCount", invoiceRepository.count());
			count.put("expenseCount", expenseRepository.count());
			return JsonResponse.success(count);
		} catch (Exception e) {
			e.printStackTrace();
			log.error(e.getMessage());
			return JsonResponse.error(e.getMessage());
		}
	}
	
	
	/**
	 * 通用模块新增
	 * @param className
	 * @param request
	 * @return
	 */
	@ResponseBody
	@RequestMapping("newAdd")
	public JsonResponse newAdd(HttpServletRequest request) {
		try {
			Map<String, Object> map = ApplicationUtils.getRequestDatas();
			String json = JSON.toJSONString(map);
			Project vo = JSON.parseObject(json, Project.class);
			projectService.save(vo);
			return JsonResponse.success();
		} catch (Exception e) {
			e.printStackTrace();
			log.error(e.getMessage());
			return JsonResponse.error(e.getMessage());
		}
	}
	
	/**
	 * 通用模块编辑
	 * @param className
	 * @param request
	 * @return
	 */
	@ResponseBody
	@RequestMapping("modify")
	public JsonResponse modify(HttpServletRequest request) {
		try {
			Map<String, Object> map = ApplicationUtils.getRequestDatas();
			/*
			 *忽略属性，多个值用,号分隔如：menuName,menuIcon,menuOrder 
			 */
			String[] ignoreProperties = null; 
			String ignore = request.getParameter("ignoreProperties");
			if(StringUtils.isNotBlank(ignore)){
				ignoreProperties = ignore.split(",");
				for(String temp: ignoreProperties){
					map.remove(temp);
				}
			}
			
			Project oldVo = projectRepository.findOne(map.get(PkEntity.PRIMARY_KEY_NAME).toString());
			String oldJson = JSON.toJSONString(oldVo);
			@SuppressWarnings("unchecked")
			Map<String, Object> oldMap = JSON.parseObject(oldJson, Map.class);
			oldMap.putAll(map);
			
			String json = JSON.toJSONString(oldMap) ;
			
			Project newVo = JSON.parseObject(json, oldVo.getClass());
			
			projectService.save(newVo);
			return JsonResponse.success();
		} catch (Exception e) {
			e.printStackTrace();
			log.error(e.getMessage());
			return JsonResponse.error(e.getMessage());
		}
	}
	
	/**
	 * 流程执行
	 * @param request
	 * @return
	 */
	@ResponseBody
	@RequestMapping("action/{projectId}")
	public JsonResponse action(HttpServletRequest request,@PathVariable String projectId) {
		try {
			if(StringUtils.isNotBlank(projectId)){
				Map<String, Object> map = ApplicationUtils.getRequestDatas();
				Project project = projectRepository.findOne(projectId);
				//1.
				if(StringUtils.isBlank(project.getFlowId())){
					return JsonResponse.error("未指定流程模板！"); 
				}
				//2
				Flow templ = flowService.getFlowRepository().findOne(project.getFlowId());
				if(templ==null){
					return JsonResponse.error("当前流程模板不存在！"); 
				}
				//3
				Boolean flag = flowService.isRight(ApplicationUtils.userId(), projectId, templ.getId());
				if(flag==false){
					return JsonResponse.error("您无权执行当前流程！"); 
				}
				//System.out.println(map);
				projectService.action(map, projectId);
				return JsonResponse.success();
			}else{
				return JsonResponse.error("立项主键Id为空！");
			}
		} catch (Exception e) {
			e.printStackTrace();
			log.error(e.getMessage());
			return JsonResponse.error(e.getMessage());
		}
	}
	
	/**
	 * 流程驳回
	 * @param request
	 * @param projectId
	 * @return
	 */
	@ResponseBody
	@RequestMapping("back/{projectId}")
	public JsonResponse back(HttpServletRequest request,@PathVariable String projectId) {
		try {
			if(StringUtils.isNotBlank(projectId)){
				Project project = projectRepository.findOne(projectId);
				//1.
				if(StringUtils.isBlank(project.getFlowId())){
					return JsonResponse.error("未指定流程模板！"); 
				}
				//2
				Flow templ = flowService.getFlowRepository().findOne(project.getFlowId());
				if(templ==null){
					return JsonResponse.error("当前流程模板不存在！"); 
				}
				//3
				Boolean flag = flowService.isRight(ApplicationUtils.userId(), projectId, templ.getId());
				if(flag==false){
					return JsonResponse.error("您无权执行当前流程！"); 
				}
				Flow firstNode = flowService.getFirstNode(project.getFlowId());
				Flow currentNode = flowService.getCurrentNode(project.getFlowId(), projectId);
				if(firstNode==currentNode){
					return JsonResponse.error("当前为【"+firstNode.getFlowName()+"】节点，无法执行驳回！"); 
				}
				projectService.back(projectId);
				return JsonResponse.success();
			}else{
				return JsonResponse.error("立项主键Id为空！");
			}
		} catch (Exception e) {
			e.printStackTrace();
			log.error(e.getMessage());
			return JsonResponse.error(e.getMessage());
		}
	}
	
	/**
	 * 处理流程路由页面
	 * @param modleName
	 * @param req
	 * @return
	 */
	@GetMapping("actionPage/{projectId}")
	public String index(@PathVariable String projectId, HttpServletRequest req) {
		Project project = projectRepository.findOne(projectId);
		Flow node = flowService.getCurrentNode(project.getFlowId(), projectId);
		if(node==null){
			node = flowService.getFirstNode(project.getFlowId());
		}
		if(node==null){
			node = new Flow();node.setFlowCode("Error");
		}
		req.setAttribute("node", node);
		return SysPath.BACK_PATH.concat("/projectNode/").concat(node.getFlowCode());
	}
	
	@ResponseBody
	@RequestMapping("taskList")
	public Object taskList(DataGrid grid,HttpServletRequest request) {
		try {
			if(grid==null) grid = new DataGrid();
			//PageRequest pageable = PageHeper.pageRequest(request);
			//User user = ApplicationUtils.User();
			String pNo = request.getParameter("pNo");
			if(StringUtils.isBlank(pNo)){
				pNo = "";
			} 
			List<Object> list = projectRepository.getTasks(ApplicationUtils.userId(),pNo);
			if(list!=null){
				List<Task> rows  = Task.getList(list);
				grid = DataGrid.gridBuilder(rows);
			}
		} catch (Exception e) {
			grid = DataGrid.gridBuilder(new ArrayList<Object>());
			e.printStackTrace();
			log.error(e.getMessage());
		}
		return grid;
	}

	
	@ResponseBody
	@RequestMapping( "batchImport")
	public JsonResponse batchImport(HttpServletRequest request) {
		try {
			Integer count = 0;
			String attachmentId = request.getParameter("attachmentId");
			if(StringUtils.isNotBlank(attachmentId)){
					String[] ids = attachmentId.split(",");
					for(String id: ids){
							if(StringUtils.isBlank(id)) continue;
							Attachment attachment = attachmentRepository.findOne(id);
							List<List<String>> data = ExcelUtils.readData(attachment.getUrl());
							if(data==null || data.size()==0)  return  JsonResponse.error("导入模板格式有误，请选择正确模板！");
							
							String title = (data!=null && data.size()>0) ? JSON.toJSONString(data.get(0))  :  "" ;
							System.out.println(title);
							
							String fixTitle = "[\"资产编号\",\"资产类别\",\"年份\",\"资产名称\",\"购进日期\",\"规格型号\",\"计量单位\",\"数量\",\"原值(金额)\",\"估计现值\",\"使用部门\",\"使用人\",\"资产状态\",\"创建时间\",\"创建人\"]";
							/**
							 * 删除标题行
							 */
							if(data.size()>0){
								data.remove(0);
							}
							
							if(PROJECT_TITLE.equals(title)){
								List<Project> pList = Project.excelDataFormat(data);
								if(!CollectionUtils.isEmpty(pList)){
									projectRepository.save(pList);
									count += pList.size();
								}
							}else if(UNIT_TITLE.equals(title)){
								List<AssistUnit> unitList = AssistUnit.excelDataFormat(data);
								if(!CollectionUtils.isEmpty(unitList)){
									assistUnitRepository.save(unitList);
									count += unitList.size();
								}
							}else if(CONTRACT_TITLE.equals(title)){
								List<Contract> cList = Contract.excelDataFormat(data);
								if(!CollectionUtils.isEmpty(cList)){
									contractRepository.save(cList);
									count += cList.size();
								}
							}else if(INFORMATION_TITLE.equals(title)){
								List<Information> iList = Information.excelDataFormat(data);
								if(!CollectionUtils.isEmpty(iList)){
									informationRepository.save(iList);
									count += iList.size();
								}
							}else if(INVOICE_TITLE.equals(title)){
								List<Invoice> iList = Invoice.excelDataFormat(data);
								if(!CollectionUtils.isEmpty(iList)){
									invoiceRepository.save(iList);
									count += iList.size();
								}
							}else if(INCOME_TITLE.equals(title)){
								List<Income> iList = Income.excelDataFormat(data);
								if(!CollectionUtils.isEmpty(iList)){
									incomeRepository.save(iList);
									count += iList.size();
								}
							}else if(EXPENSE_TITLE.equals(title)){
								List<Expense> eList = Expense.excelDataFormat(data);
								if(!CollectionUtils.isEmpty(eList)){
									expenseRepository.save(eList);
									count += eList.size();
								}
							}else if(MATERIEL_TITLE.equals(title)){
								List<Materiel> mList = Materiel.excelDataFormat(data);
								if(!CollectionUtils.isEmpty(mList)){
									materielRepository.save(mList);
									count += mList.size();
								}
							}else if(fixTitle.equals(title)){
								List<FixedAssets> mList = FixedAssets.excelDataFormat(data);
								if(!CollectionUtils.isEmpty(mList)){
									FixedAssetsRepository fixedAssetsRepository = (FixedAssetsRepository) ApplicationUtils.getBean("fixedAssetsRepository");
									fixedAssetsRepository.save(mList);
									count += mList.size();
								}
							}
							
							else{
								log.info(title + "【此数据模板未实现】!");
							}
							attachmentRepository.delete(attachment);
					}
			}
			return JsonResponse.success("成功导入："+ count + "条数据！");
		} catch (Exception e) {
			e.printStackTrace();
			log.error(e.getMessage());
			return JsonResponse.error(e.getMessage());
		}
	}
	
	/**
	 * 工程导入标题
	 */
	private static String PROJECT_TITLE = "[\"工程路段编号\",\"工程段落\",\"项目状态\",\"专业类别\",\"订单编号\",\"项目名称\",\"立项预算\",\"完工预算\",\"设计长度\",\"项目经理\",\"市场负责人\",\"建设单位\",\"设计单位\",\"运营商\",\"工程经理\",\"所属机构\",\"订单日期\",\"是否分包\",\"分包比例\",\"区域\",\"优先级\",\"备注\",\"创建时间\",\"创建人\"]";
	
	/**
	 * 合作单位导入标题
	 */
	private static String UNIT_TITLE = "[\"单位名称\",\"联系人\",\"联系电话\",\"收款人\",\"收款帐号\",\"开户行\",\"单位类别\"]";
	/**
	 * 合同模板标题
	 */
	private static String CONTRACT_TITLE="[\"订单编号\",\"订单名称\",\"合同编号\",\"合同类型\",\"合同名称\",\"签订日期\",\"合同甲方\",\"合同乙方\",\"甲方经办人\",\"甲方联系电话\",\"乙方经办人\",\"乙方联系电话\",\"预算金额\",\"实际金额\",\"开票金额\",\"审计金额\",\"回款金额\",\"付款情况及说明\",\"总包单位\",\"分包单位\"]";

	/**
	 * 施工信息模板标题
	 */
	private static String INFORMATION_TITLE= "[\"项目编号\",\"分包合同\",\"施工单位\",\"施工负责人\",\"施工负责人电话\",\"开工时间\",\"完工时间\",\"验收时间\",\"监理单位\",\"监理人\",\"监理电话\",\"工期（天数）\",\"工作量描述\",\"实际芯数\",\"实际米数\",\"资料员\",\"是否合放\",\"本地网长度\",\"电力长度\"]";
	
	/**
	 * 开票信息模板标题
	 */
	private static String INVOICE_TITLE = "[\"开票编号(总包)\",\"发票标题(总包)\",\"开票编号(分包)\",\"发票标题(分包)\",\"合同(项目)编号\",\"开票人\",\"开票日期\",\"外经证\",\"开票金额\",\"经办人\",\"发票类型\",\"税率\",\"发票种类\",\"备注\",\"不含税金额\",\"税额\"]";

	/**
	 * 收入模板标题
	 */
	private static String INCOME_TITLE="[\"项目编号\",\"回款金额\",\"回款日期\",\"回款确认人\",\"凭单号\",\"备注\"]";
	/**
	 * 支出模板标题
	 */
	private static String EXPENSE_TITLE="[\"段落编号\",\"支出金额\",\"费用类别\",\"申请日期\",\"申请人\",\"凭单号\",\"备注\",\"审批状态\",\"审批建议\",\"项目部\"]";

	/**
	 * 物料管理导入数据模板
	 */
	private static String MATERIEL_TITLE="[\"物料编码\",\"物料名称\",\"规格\",\"单位\"]";

}
